package com.bodu.core.common;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.bodu.core.entity.CommonEntity;
import com.bodu.core.entity.ParamReq;
import com.bodu.core.entity.enums.DelFlagEnum;
import com.bodu.core.entity.enums.StatusFlagEnum;
import com.bodu.core.entity.result.PageResult;
import com.bodu.core.entity.result.Result;
import com.bodu.core.exception.custom.*;

import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author gaoya
 * @Description 抽象 Controller
 * @date 2022 - 10 - 17 22:54:17
 */
public abstract class AbstractCommonController<S extends CommonService, E extends CommonEntity, R extends CommonEntity>
        implements CommonController<S, E, R> , ExtCommonController{

    @Override
    public Result getModel(S service, Long id) {
        return Result.success(service.getModel(id));
    }

    @Override
    public Result<Integer> save(S service, E request) throws SaveException {
        request.setDelFlag(DelFlagEnum.NO.getValue());
        request.setStatusFlag(StatusFlagEnum.USE.getValue());
        request.setCreateUser(this.getLoginUserId());
        request.setCreateTime(DateUtil.date());
        return Result.success(service.save(request));
    }

    @Override
    public Result<Integer> update(S service, E request) throws UpdateException {
        request.setCreateUser(getLoginUserId());
        request.setUpdateTime(DateUtil.date());
        return Result.success(service.update(request));
    }

    @Override
    public Result<List<R>> listPage(S service, ParamReq<E> req) throws ListException {
        if (ObjectUtil.isEmpty(req.getEntityDelFlag())) {
            req.setEntityDelFlag(DelFlagEnum.NO.getValue());
        }
        req.setReqStartIndex();
        List<E> list = service.listPage(req);
        return Result.success(list);
    }

    @Override
    public Result<Integer> countPage(S service, ParamReq<E> req) throws ListCountException {
        if (ObjectUtil.isEmpty(req.getEntityDelFlag())) {
            req.setEntityDelFlag(DelFlagEnum.NO.getValue());
        }
        return Result.success(service.countPage(req));
    }

    @Override
    public Result<PageResult> page(S service, ParamReq<E> req) throws PageException {
        if (ObjectUtil.isEmpty(req.getEntityDelFlag())) {
            req.setEntityDelFlag(DelFlagEnum.NO.getValue());
        }
        req.setReqStartIndex();
        List<E> list = service.listPage(req);
        Integer count = service.countPage(req);
        PageResult pageResult = PageResult.builder(list, count);
        return Result.success(pageResult);
    }

    @Override
    public Result<Integer> delete(S service, Long id) throws DeleteException {
        return Result.success(service.updateDelFlagById(id, DelFlagEnum.YES.getValue()));
    }

    @Override
    public Result<Integer> batchDelete(S service, List<Long> ids) throws DeleteException {
        AtomicReference<Integer> count = new AtomicReference<>(0);
        ids.forEach(id -> count.updateAndGet(v -> v + service.updateDelFlagById(id, DelFlagEnum.YES.getValue())));
        return Result.success(count.get());
    }
}
